{
 "cells": [
  {
   "cell_type": "code",
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-08-26T04:21:07.052692Z",
     "start_time": "2025-08-26T04:21:07.021001Z"
    }
   },
   "source": [
    "from langchain.chat_models.tongyi import ChatTongyi\n",
    "\n",
    "import os\n",
    "\n",
    "with open(\"api_key.txt\", \"r\") as f:\n",
    "    api_key = f.read()\n",
    "\n",
    "os.environ[\"DASHSCOPE_API_KEY\"] = api_key\n",
    "\n",
    "llm = ChatTongyi(model=\"qwen-plus\")\n",
    "\n",
    "from langchain_tavily import TavilySearch\n",
    "\n",
    "with open(\"./search_api_key\", \"r\") as f:\n",
    "    search_api_key = f.read()\n",
    "\n",
    "os.environ[\"TAVILY_API_KEY\"] = search_api_key\n",
    "\n",
    "from typing import Annotated\n",
    "from typing_extensions import TypedDict\n",
    "\n",
    "from langgraph.graph.message import add_messages\n",
    "\n",
    "\n",
    "class State(TypedDict):\n",
    "    messages: Annotated[list, add_messages]\n",
    "    birthday: str\n",
    "    name: str\n",
    "\n",
    "\n",
    "from langgraph.graph import StateGraph, START, END\n",
    "\n",
    "graph_builder = StateGraph(State)\n",
    "\n",
    "from langgraph.types import Command, interrupt\n",
    "from langchain_core.tools import tool, InjectedToolCallId\n",
    "from langchain_core.messages import ToolMessage\n",
    "\n",
    "\n",
    "@tool\n",
    "def human_assistance(name: str, birthday: str, tool_call_id: Annotated[str, InjectedToolCallId]) -> str:\n",
    "    \"\"\"Request assistance from a human.\"\"\"\n",
    "    human_response = interrupt(\n",
    "        {\n",
    "            \"question\": \"IS this correct?\",\n",
    "            \"name\": name,\n",
    "            \"birthday\": birthday,\n",
    "        }\n",
    "    )\n",
    "    if human_response.get(\"correct\", \"\").lower().startswith(\"y\"):\n",
    "        verified_name = name\n",
    "        verified_birthday = birthday\n",
    "        response = \"Correct\"\n",
    "    else:\n",
    "        verified_name = human_response.get(\"name\", \"\")\n",
    "        verified_birthday = human_response.get(\"birthday\", birthday)\n",
    "        response = f\"Made a correction: {human_response}\"\n",
    "\n",
    "    state_update = {\n",
    "        \"name\": verified_name,\n",
    "        \"birthday\": birthday,\n",
    "        \"messages\": [ToolMessage(response, tool_call_id=tool_call_id)]\n",
    "    }\n",
    "    return Command(update=state_update)\n",
    "\n",
    "\n",
    "tool_search = TavilySearch(max_results=2)\n",
    "tools = [tool_search, human_assistance]\n",
    "\n",
    "llm_tool = llm.bind_tools(tools=tools)\n",
    "\n",
    "\n",
    "def chatbot(state: State):\n",
    "    message = llm_tool.invoke(state[\"messages\"])\n",
    "    assert len(message.tool_calls) <= 1\n",
    "    return {\"messages\": [message]}\n",
    "\n",
    "\n",
    "graph_builder.add_node(\"chatbot\", chatbot)\n",
    "\n",
    "from langgraph.prebuilt import ToolNode, tools_condition\n",
    "\n",
    "tool_node = ToolNode(tools=tools)\n",
    "\n",
    "graph_builder.add_node(\"tools\", tool_node)\n",
    "\n",
    "graph_builder.add_conditional_edges(\n",
    "    \"chatbot\",\n",
    "    tools_condition\n",
    ")\n",
    "\n",
    "graph_builder.add_edge(\"tools\", \"chatbot\")\n",
    "\n",
    "graph_builder.add_edge(START, \"chatbot\")\n",
    "\n",
    "from langgraph.checkpoint.memory import InMemorySaver\n",
    "\n",
    "memory = InMemorySaver()\n",
    "graph = graph_builder.compile(checkpointer=memory)\n",
    "\n",
    "\n"
   ],
   "outputs": [],
   "execution_count": 50
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-26T04:21:13.449168Z",
     "start_time": "2025-08-26T04:21:07.063381Z"
    }
   },
   "cell_type": "code",
   "source": [
    "user_input = (\n",
    "    \"Can you look up when LangGraph was released? \"\n",
    "    \"When you have the answer, use the human_assistance tool for review.\"\n",
    ")\n",
    "config = {\"configurable\": {\"thread_id\": \"1\"}}\n",
    "\n",
    "events = graph.stream(\n",
    "    {\"messages\": [{\"role\": \"user\", \"content\": user_input}]},\n",
    "    config,\n",
    "    stream_mode=\"values\",\n",
    ")\n",
    "for event in events:\n",
    "    if \"messages\" in event:\n",
    "        event[\"messages\"][-1].pretty_print()"
   ],
   "id": "68f41f455e4913b4",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "================================\u001B[1m Human Message \u001B[0m=================================\n",
      "\n",
      "Can you look up when LangGraph was released? When you have the answer, use the human_assistance tool for review.\n",
      "==================================\u001B[1m Ai Message \u001B[0m==================================\n",
      "Tool Calls:\n",
      "  tavily_search (call_5571863953394b158f8f2b)\n",
      " Call ID: call_5571863953394b158f8f2b\n",
      "  Args:\n",
      "    query: LangGraph release date\n",
      "=================================\u001B[1m Tool Message \u001B[0m=================================\n",
      "Name: tavily_search\n",
      "\n",
      "{\"query\": \"LangGraph release date\", \"follow_up_questions\": null, \"answer\": null, \"images\": [], \"results\": [{\"url\": \"https://langchain-ai.github.io/langgraph/tutorials/get-started/5-customize-state/\", \"title\": \"5. Customize state - GitHub Pages\", \"content\": \"Prompt the chatbot to look up the \\\"birthday\\\" of the LangGraph library and direct the chatbot to reach out to the `human_assistance` tool once it has the required information. Then, I'll use the human_assistance tool for review.\\\", 'type': 'text'}, {'id': 'toolu_01JoXQPgTVJXiuma8xMVwqAi', 'input': {'query': 'LangGraph release date'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}] \\\\n\\\\nGiven this information, I'll use the human_assistance tool to review and potentially provide more accurate information about LangGraph's initial release date.\\\", 'type': 'text'}, {'id': 'toolu_01JDQAV7nPqMkHHhNs3j3XoN', 'input': {'name': 'Assistant', 'birthday': '2023-01-01'}, 'name': 'human_assistance', 'type': 'tool_use'}] \\\\n\\\\nGiven this information, I'll use the human_assistance tool to review and potentially provide more accurate information about LangGraph's initial release date.\\\", 'type': 'text'}, {'id': 'toolu_01JDQAV7nPqMkHHhNs3j3XoN', 'input': {'name': 'Assistant', 'birthday': '2023-01-01'}, 'name': 'human_assistance', 'type': 'tool_use'}]\", \"score\": 0.8127637, \"raw_content\": null}, {\"url\": \"https://pypi.org/project/langgraph/\", \"title\": \"langgraph\", \"content\": \"langgraph · PyPI langgraph 0.6.4 Image 5: LangGraph Logo Install LangGraph: from langgraph.prebuilt import create_react_agent Or, to learn how to build an agent workflow with a customizable architecture, long-term memory, and other complex task handling, see the LangGraph basics tutorials. LangGraph provides low-level supporting infrastructure for _any_ long-running, stateful workflow or agent. While LangGraph can be used standalone, it also integrates seamlessly with any LangChain product, giving developers a full suite of tools for building agents. *   LangGraph Platform — Deploy and scale agents effortlessly with a purpose-built deployment platform for long running, stateful workflows. 0.3.0 yanked Feb 26, 2025 Reason this release was yanked: Missing dependency on langgraph-prebuilt Details for the file `langgraph-0.6.4.tar.gz`. Details for the file `langgraph-0.6.4-py3-none-any.whl`.\", \"score\": 0.71425, \"raw_content\": null}], \"response_time\": 2.8, \"request_id\": \"ae7f339a-a65a-4ce0-a4c3-206f6b76207a\"}\n",
      "==================================\u001B[1m Ai Message \u001B[0m==================================\n",
      "Tool Calls:\n",
      "  human_assistance (call_4b9a638f05cc49139878ee)\n",
      " Call ID: call_4b9a638f05cc49139878ee\n",
      "  Args:\n",
      "    name: LangGraph\n",
      "    birthday: 2024-03-15\n"
     ]
    }
   ],
   "execution_count": 51
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-26T04:21:15.209767Z",
     "start_time": "2025-08-26T04:21:13.466516Z"
    }
   },
   "cell_type": "code",
   "source": [
    "human_command = Command(\n",
    "    resume={\n",
    "        \"name\": \"LangGraph\",\n",
    "        \"birthday\": \"Jan 17, 2024\",\n",
    "    },\n",
    ")\n",
    "\n",
    "events = graph.stream(human_command, config, stream_mode=\"values\")\n",
    "for event in events:\n",
    "    if \"messages\" in event:\n",
    "        event[\"messages\"][-1].pretty_print()"
   ],
   "id": "b85f20ce05294a2f",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "==================================\u001B[1m Ai Message \u001B[0m==================================\n",
      "Tool Calls:\n",
      "  human_assistance (call_4b9a638f05cc49139878ee)\n",
      " Call ID: call_4b9a638f05cc49139878ee\n",
      "  Args:\n",
      "    name: LangGraph\n",
      "    birthday: 2024-03-15\n",
      "=================================\u001B[1m Tool Message \u001B[0m=================================\n",
      "Name: human_assistance\n",
      "\n",
      "Made a correction: {'name': 'LangGraph', 'birthday': 'Jan 17, 2024'}\n",
      "==================================\u001B[1m Ai Message \u001B[0m==================================\n",
      "\n",
      "LangGraph was released on January 17, 2024.\n"
     ]
    }
   ],
   "execution_count": 52
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-26T04:21:15.241112Z",
     "start_time": "2025-08-26T04:21:15.226578Z"
    }
   },
   "cell_type": "code",
   "source": [
    "snapshot = graph.get_state(config)\n",
    "print(snapshot.values.items())\n",
    "{k:v for k, v in snapshot.values.items() if k in (\"name\", \"birthday\")}"
   ],
   "id": "8e8cf5dd93f4584d",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dict_items([('messages', [HumanMessage(content='Can you look up when LangGraph was released? When you have the answer, use the human_assistance tool for review.', additional_kwargs={}, response_metadata={}, id='45a4fdea-4eae-4313-acee-c14f1ece3b0a'), AIMessage(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_5571863953394b158f8f2b', 'type': 'function', 'function': {'name': 'tavily_search', 'arguments': '{\"query\": \"LangGraph release date\"}'}}]}, response_metadata={'model_name': 'qwen-plus', 'finish_reason': 'tool_calls', 'request_id': '24914717-185b-964e-947f-7c44a62688ac', 'token_usage': {'input_tokens': 1895, 'output_tokens': 24, 'total_tokens': 1919, 'prompt_tokens_details': {'cached_tokens': 0}}}, id='run--e01a2208-89df-4472-af4c-6a0632ef1710-0', tool_calls=[{'name': 'tavily_search', 'args': {'query': 'LangGraph release date'}, 'id': 'call_5571863953394b158f8f2b', 'type': 'tool_call'}]), ToolMessage(content='{\"query\": \"LangGraph release date\", \"follow_up_questions\": null, \"answer\": null, \"images\": [], \"results\": [{\"url\": \"https://langchain-ai.github.io/langgraph/tutorials/get-started/5-customize-state/\", \"title\": \"5. Customize state - GitHub Pages\", \"content\": \"Prompt the chatbot to look up the \\\\\"birthday\\\\\" of the LangGraph library and direct the chatbot to reach out to the `human_assistance` tool once it has the required information. Then, I\\'ll use the human_assistance tool for review.\\\\\", \\'type\\': \\'text\\'}, {\\'id\\': \\'toolu_01JoXQPgTVJXiuma8xMVwqAi\\', \\'input\\': {\\'query\\': \\'LangGraph release date\\'}, \\'name\\': \\'tavily_search_results_json\\', \\'type\\': \\'tool_use\\'}] \\\\\\\\n\\\\\\\\nGiven this information, I\\'ll use the human_assistance tool to review and potentially provide more accurate information about LangGraph\\'s initial release date.\\\\\", \\'type\\': \\'text\\'}, {\\'id\\': \\'toolu_01JDQAV7nPqMkHHhNs3j3XoN\\', \\'input\\': {\\'name\\': \\'Assistant\\', \\'birthday\\': \\'2023-01-01\\'}, \\'name\\': \\'human_assistance\\', \\'type\\': \\'tool_use\\'}] \\\\\\\\n\\\\\\\\nGiven this information, I\\'ll use the human_assistance tool to review and potentially provide more accurate information about LangGraph\\'s initial release date.\\\\\", \\'type\\': \\'text\\'}, {\\'id\\': \\'toolu_01JDQAV7nPqMkHHhNs3j3XoN\\', \\'input\\': {\\'name\\': \\'Assistant\\', \\'birthday\\': \\'2023-01-01\\'}, \\'name\\': \\'human_assistance\\', \\'type\\': \\'tool_use\\'}]\", \"score\": 0.8127637, \"raw_content\": null}, {\"url\": \"https://pypi.org/project/langgraph/\", \"title\": \"langgraph\", \"content\": \"langgraph · PyPI langgraph 0.6.4 Image 5: LangGraph Logo Install LangGraph: from langgraph.prebuilt import create_react_agent Or, to learn how to build an agent workflow with a customizable architecture, long-term memory, and other complex task handling, see the LangGraph basics tutorials. LangGraph provides low-level supporting infrastructure for _any_ long-running, stateful workflow or agent. While LangGraph can be used standalone, it also integrates seamlessly with any LangChain product, giving developers a full suite of tools for building agents. *   LangGraph Platform — Deploy and scale agents effortlessly with a purpose-built deployment platform for long running, stateful workflows. 0.3.0 yanked Feb 26, 2025 Reason this release was yanked: Missing dependency on langgraph-prebuilt Details for the file `langgraph-0.6.4.tar.gz`. Details for the file `langgraph-0.6.4-py3-none-any.whl`.\", \"score\": 0.71425, \"raw_content\": null}], \"response_time\": 2.8, \"request_id\": \"ae7f339a-a65a-4ce0-a4c3-206f6b76207a\"}', name='tavily_search', id='b9c94816-012a-4015-be22-4ada5c850055', tool_call_id='call_5571863953394b158f8f2b'), AIMessage(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_4b9a638f05cc49139878ee', 'type': 'function', 'function': {'name': 'human_assistance', 'arguments': '{\"name\": \"LangGraph\", \"birthday\": \"2024-03-15\"}'}}]}, response_metadata={'model_name': 'qwen-plus', 'finish_reason': 'tool_calls', 'request_id': '94afeaaa-9c99-9600-a102-a557431e61e5', 'token_usage': {'input_tokens': 2647, 'output_tokens': 36, 'total_tokens': 2683, 'prompt_tokens_details': {'cached_tokens': 1792}}}, id='run--29f8d0b7-1f85-4ac9-a00b-b62597cffd80-0', tool_calls=[{'name': 'human_assistance', 'args': {'name': 'LangGraph', 'birthday': '2024-03-15'}, 'id': 'call_4b9a638f05cc49139878ee', 'type': 'tool_call'}]), ToolMessage(content=\"Made a correction: {'name': 'LangGraph', 'birthday': 'Jan 17, 2024'}\", name='human_assistance', id='0ad17b42-2bd9-4eb3-ba7b-f58b1ea78539', tool_call_id='call_4b9a638f05cc49139878ee'), AIMessage(content='LangGraph was released on January 17, 2024.', additional_kwargs={}, response_metadata={'model_name': 'qwen-plus', 'finish_reason': 'stop', 'request_id': '53b68ba9-731a-9432-8cd7-2a1569b8f7a6', 'token_usage': {'input_tokens': 2722, 'output_tokens': 16, 'total_tokens': 2738, 'prompt_tokens_details': {'cached_tokens': 0}}}, id='run--ed67dcd4-2926-461e-81ba-24a67542f46d-0')]), ('birthday', '2024-03-15'), ('name', 'LangGraph')])\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'birthday': '2024-03-15', 'name': 'LangGraph'}"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 53
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-26T04:21:15.381685Z",
     "start_time": "2025-08-26T04:21:15.374843Z"
    }
   },
   "cell_type": "code",
   "source": "graph.update_state(config, {\"name\": \"LangGraph(library)\"})",
   "id": "ed60897a96b37e1d",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'configurable': {'thread_id': '1',\n",
       "  'checkpoint_ns': '',\n",
       "  'checkpoint_id': '1f082341-b247-6a66-8006-a3aeaf77bd30'}}"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 54
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-26T04:21:39.508885Z",
     "start_time": "2025-08-26T04:21:39.490146Z"
    }
   },
   "cell_type": "code",
   "source": [
    "snapshot = graph.get_state(config)\n",
    "\n",
    "{k:v for k, v in snapshot.values.items() if k in (\"name\", \"birthday\")}"
   ],
   "id": "2f8423745362869d",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'birthday': '2024-03-15', 'name': 'LangGraph(library)'}"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 56
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-26T06:09:14.004369Z",
     "start_time": "2025-08-26T06:09:13.981578Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import langgraph\n",
    "print(dir(langgraph))"
   ],
   "id": "ff62d68d7c60cb9e",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '_internal', 'cache', 'channels', 'checkpoint', 'config', 'constants', 'errors', 'graph', 'managed', 'prebuilt', 'pregel', 'runtime', 'store', 'types', 'typing', 'warnings']\n"
     ]
    }
   ],
   "execution_count": 57
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-26T06:47:24.414223Z",
     "start_time": "2025-08-26T06:47:24.301832Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langgraph_sdk import get_client\n",
    "import asyncio\n",
    "\n",
    "client = get_client(url=\"http://localhost:2024\")\n",
    "\n",
    "async def main():\n",
    "    async for chunk in client.runs.stream(\n",
    "        None,  # Threadless run\n",
    "        \"agent\", # Name of assistant. Defined in langgraph.json.\n",
    "        input={\n",
    "        \"messages\": [{\n",
    "            \"role\": \"human\",\n",
    "            \"content\": \"What is LangGraph?\",\n",
    "            }],\n",
    "        },\n",
    "    ):\n",
    "        print(f\"Receiving new event of type: {chunk.event}...\")\n",
    "        print(chunk.data)\n",
    "        print(\"\\n\\n\")\n",
    "\n",
    "asyncio.run(main())"
   ],
   "id": "a2a93890fba003a8",
   "outputs": [
    {
     "ename": "RuntimeError",
     "evalue": "asyncio.run() cannot be called from a running event loop",
     "output_type": "error",
     "traceback": [
      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[1;31mRuntimeError\u001B[0m                              Traceback (most recent call last)",
      "Cell \u001B[1;32mIn[58], line 21\u001B[0m\n\u001B[0;32m     18\u001B[0m         \u001B[38;5;28mprint\u001B[39m(chunk\u001B[38;5;241m.\u001B[39mdata)\n\u001B[0;32m     19\u001B[0m         \u001B[38;5;28mprint\u001B[39m(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;130;01m\\n\u001B[39;00m\u001B[38;5;130;01m\\n\u001B[39;00m\u001B[38;5;124m\"\u001B[39m)\n\u001B[1;32m---> 21\u001B[0m \u001B[43masyncio\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mrun\u001B[49m\u001B[43m(\u001B[49m\u001B[43mmain\u001B[49m\u001B[43m(\u001B[49m\u001B[43m)\u001B[49m\u001B[43m)\u001B[49m\n",
      "File \u001B[1;32mD:\\anaconda\\lib\\asyncio\\runners.py:33\u001B[0m, in \u001B[0;36mrun\u001B[1;34m(main, debug)\u001B[0m\n\u001B[0;32m      9\u001B[0m \u001B[38;5;124;03m\"\"\"Execute the coroutine and return the result.\u001B[39;00m\n\u001B[0;32m     10\u001B[0m \n\u001B[0;32m     11\u001B[0m \u001B[38;5;124;03mThis function runs the passed coroutine, taking care of\u001B[39;00m\n\u001B[1;32m   (...)\u001B[0m\n\u001B[0;32m     30\u001B[0m \u001B[38;5;124;03m    asyncio.run(main())\u001B[39;00m\n\u001B[0;32m     31\u001B[0m \u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[0;32m     32\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m events\u001B[38;5;241m.\u001B[39m_get_running_loop() \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[1;32m---> 33\u001B[0m     \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mRuntimeError\u001B[39;00m(\n\u001B[0;32m     34\u001B[0m         \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124masyncio.run() cannot be called from a running event loop\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n\u001B[0;32m     36\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m coroutines\u001B[38;5;241m.\u001B[39miscoroutine(main):\n\u001B[0;32m     37\u001B[0m     \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mValueError\u001B[39;00m(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124ma coroutine was expected, got \u001B[39m\u001B[38;5;132;01m{!r}\u001B[39;00m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;241m.\u001B[39mformat(main))\n",
      "\u001B[1;31mRuntimeError\u001B[0m: asyncio.run() cannot be called from a running event loop"
     ]
    }
   ],
   "execution_count": 58
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": "",
   "id": "292294b9b370ca39"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
